/*  PageRetriever.Java
 * 
 *  WebCrawler Program
 *  @author Amandeep Jhajj and Craig Markham
 *  @date 26Apr2012
 */

package Crawler;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.LinkedList;
import java.util.List;
import java.util.Observable;
import java.util.concurrent.BlockingQueue;

public class PageRetriever extends Observable implements Runnable {

	private static final String LINE_END = "\n";

	private final BlockingQueue<List<String>> my_page_q;

	private final URL my_url;

	public PageRetriever(URL the_url, BlockingQueue<List<String>> the_page_buffer) {
		my_page_q = the_page_buffer;
		my_url = the_url;	
	}


	private List<String> bytesToStrings(final String the_url, final byte[] the_content) {
		
		final List<String> lines = new LinkedList<String>();
		final String[] page_array = (new String(the_content)).split(LINE_END);
		
		lines.add(the_url);
		
		for (String line : page_array) {
			lines.add(line);
		}
		//System.out.println(lines);
		return lines;
		
	}
	
	
    protected byte[] readStream(final int length, final InputStream stream )
    throws java.io.IOException {
	    final int buflen = 
	    	Math.max( 1024, Math.max( length, stream.available() ) );
	    byte[] buf   = new byte[buflen];;
	    byte[] bytes = null;
	
	    for ( int nRead = stream.read(buf); nRead != -1; nRead = stream.read(buf) ) {
	        if ( bytes == null ) {
	            bytes = buf;
	            buf   = new byte[buflen];
	            continue;
	        }
	        final byte[] newBytes = new byte[ bytes.length + nRead ];
	        System.arraycopy( bytes, 0, newBytes, 0, bytes.length );
	        System.arraycopy( buf, 0, newBytes, bytes.length, nRead );
	        bytes = newBytes;
	    }
	    
	    return bytes;
    }
    
	@Override
	public void run() {
		try {
			//System.out.println("PageRetriever try ran");

			final java.net.URLConnection connection = my_url.openConnection( );
	        if ( !(connection instanceof java.net.HttpURLConnection) )
	            throw new java.lang.IllegalArgumentException(
	                "URL protocol must be HTTP." );
	        final java.net.HttpURLConnection conn =
	            (java.net.HttpURLConnection)connection;
	 
	        // Set up a request.
	        conn.setConnectTimeout( 10000 );    // 10 sec
	        conn.setReadTimeout( 10000 );       // 10 sec
	        conn.setInstanceFollowRedirects( true );
	        conn.setRequestProperty( "Team I Dont Know", "Crawler TCSS422" );
	 
	        // Send the request.
	        conn.connect( );
	        
	        final int length  = conn.getContentLength( );
	 
	        // Get the content.
	        byte[] content = null;
	        
	        final InputStream stream = conn.getInputStream();
	        if ( stream != null ) {	            
					content = readStream( length, stream );				
	        } 
	        
	        conn.disconnect( );
	        
	        if (content != null) {
		        
	        	my_page_q.put(bytesToStrings("http://" + my_url.getHost() + my_url.getPath(), content));
	        	
	        }	        
	        
		} catch (final IOException e) {
			// skip the page if cannot connect to it			
		} catch (final InterruptedException e) {
			
		}

        setChanged();
		notifyObservers();

	}
}
